#ifndef __HW_RPU_H__
#define __HW_RPU_H__

#include <linux/io.h>


//#define     RPU_BASE						(0x58900000)

#define     RPU_RSA_PARA_START  0x400
#define     RPU_RSA_PARA_E_ADDR 0x404
#define     RPU_RSA_PARA_D_ADDR 0x408

#define     RPU_RSA_N_ADDR      0x000
#define     RPU_RSA_KEY_ADDR    0x100
#define     RPU_RSA_DATA_ADDR   0x200
#define     RPU_RSA_RRMODN_ADDR 0x300

#define     RPU_SM2_SIGN_DATA_ADDR 0x4b0
#define     RPU_SM2_SIGN_KEY_ADDR 0x400
#define     RPU_SM2_SIGN_RAND_ADDR 0x420
#define     RPU_SM2_SIGN_PARA_ADDR 0x000

#define     PRU_SM2_VERIFY_PX_ADDR 0X1c0
#define     PRU_SM2_VERIFY_PY_ADDR 0X1e0
#define     RPU_SM2_VERIFY_DATA_ADDR 0x000
#define     RPU_SM2_VERIFY_R_ADDR 0x020
#define     RPU_SM2_VERIFY_S_ADDR 0x040

#define     RPU_SM2_SIGN_RESULT_R_ADDR 0x500
#define     RPU_SM2_SIGN_RESULT_S_ADDR 0x520

#define     RPU_SM2_VERIFY_RESULT_ADDR 0x6e0
#define     RPU_SM2_VERIFY_INTER_RESULT_ADDR 0x680









#define     RPU_REG_OFFSET					(0x6000)

#define     RPU_WORK_REG(regbase)			(regbase + 0x0000)
#define     RPU_WORK_START_BIT				0
#define     RPU_WORK_BUSY_BIT				0

#define     RPU_OVER(regbase)				(regbase + 0X0004)

#define     RPU_INT_MASK(regbase)			(regbase + 0x0008)
#define	    RPU_INT_BIT						0

#define     RPU_INT_STATE(regbase)			(regbase + 0x000c)

#define     RPU_TCM_BASE(regbase)			(regbase + 0x0010)
#define     RPU_TCM_MASK(regbase)			(regbase + 0x0014)
#define     RPU_CACHE_BURST_SIZE(regbase)	(regbase + 0x0018)
#define     RPU_CACHE_LINE_SIZE(regbase)	(regbase + 0x001c)
#define     RPU_CACHE_START_ADDR(regbase)	(regbase + 0x0020)

#define     RPU_PLAIN_ADDR(regbase)			(regbase + 0x0030)
#define     RPU_PLAIN_SIZE(regbase)			(regbase + 0x0034)

#define     RPU_CIPHER_ADDR(regbase)		(regbase + 0x0038)
#define     RPU_CIPHER_SIZE(regbase)		(regbase + 0x003c)

#define     RPU_TCM_ADDR(regbase)			(regbase + 0x0010)
#define     RPU_ORDER_REG(regbase)			(regbase + 0x0040)

#define     RPU_ENCRYPT_MODE(regbase)		(regbase + 0x0050)
#define	    RPU_ENCRYPT_MODE_WAY			0
#define	    RPU_ENCRYPT_MODE_SIGN			1
#define     RPU_ENCRYPT_KEY_EXPAND_BIT		2
#define     RPU_ENCRYPT_INIT_SIGN_BIT		3
#define     RPU_ALG_TYPE(regbase)			(regbase + 0x0054)

#define     RPU_KEY0_REG(regbase)			(regbase + 0x0070)
#define     RPU_KEY1_REG(regbase)			(regbase + 0x0074)
#define     RPU_KEY2_REG(regbase)			(regbase + 0x0078)
#define     RPU_KEY3_REG(regbase)			(regbase + 0x007c)
#define     RPU_KEY4_REG(regbase)			(regbase + 0x0080)
#define     RPU_KEY5_REG(regbase)			(regbase + 0x0084)
#define     RPU_KEY6_REG(regbase)			(regbase + 0x0088)
#define     RPU_KEY7_REG(regbase)			(regbase + 0x008c)

#define     RPU_R0_REG(regbase)				(regbase + 0x00b0)
#define     RPU_R1_REG(regbase)				(regbase + 0x00b4)
#define     RPU_R2_REG(regbase)				(regbase + 0x00b8)
#define     RPU_R3_REG(regbase)				(regbase + 0x00bc)
#define     RPU_R4_REG(regbase)				(regbase + 0x00c0)
#define     RPU_R5_REG(regbase)				(regbase + 0x00c4)
#define     RPU_R6_REG(regbase)				(regbase + 0x00c8)
#define     RPU_R7_REG(regbase)				(regbase + 0x00cc)



//=============================rpu_alg_lib_common.h==========================

#define setbit(x, y) (x |= (1<<y))
#define clrbit(x, y) (x &= ~(1<<y))

enum sym_crypto_mode {
	ECB_MODE,
	CBC_MODE,
	UNKNOWN_MODE,
};

enum sym_operations {
	ENCRYPT_OPR,
	DECRYPT_OPR,
	UNKONWN_OPR,
};

//=============================rpu_alg_lib_rsa2048.h==========================
enum rsa_key_type {
	RSA_KEY_PUB,
	RSA_KEY_PRIV,
	UNKONWN_KEY_TYPE,
};












//===============================rpu common===============================
void rpu_start_work(void __iomem *regbase);
void rpu_stop_work(void __iomem *regbase);
void rpu_start_irq(void __iomem *regbase);
void rpu_stop_irq(void __iomem *regbase);
void rpu_clr_irq(void __iomem *regbase);
uint32_t rpu_get_int_status(void __iomem *regbase);
uint32_t rpu_get_status(void __iomem *regbase);
uint32_t rpu_get_status_cache(void __iomem *regbase);
int rpu_wait_free(void __iomem *regbase, uint32_t loop);
void para_cfg(
		void __iomem *regbase,
		uint32_t *para_ptr,
		int para_size);
void para_cfg_sbox(
		void __iomem *regbase,
		uint32_t *para_ptr,
		int para_size,
		int base_offset);
void para_read_contiue_bybyte(
		void __iomem *regbase,
		uint8_t *para_ptr,
		int para_size,
		int base_offset_start);
void para_write_contiue_bybyte(
		void __iomem *regbase,
		uint8_t *para_ptr,
		int para_size,
		int base_offset_start);
int rpu_key_setup_wait(
		void __iomem		*regbase,
		const uint8_t		key[],
		uint32_t			key_len,
		uint32_t			loop);
int rpu_iv_setup_imm(
		void __iomem		*regbase,
		uint8_t				iv[],
		uint32_t			iv_len);
int rpu_iv_get_imm(
		void __iomem		*regbase,
		uint8_t				iv[],
		uint32_t			iv_len);





//===============================rpu algorithm===============================
int rpu_aes_sha256_rsa2048_inst_init(void __iomem *regbase);
int rpu_aes_init(void __iomem *regbase);
int rpu_aes_crypto_irq(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		enum sym_operations	is_enc,
		enum sym_crypto_mode	mode,
		bool				is_init);

int rpu_sha256_init(void __iomem *regbase);
int rpu_sha256_crypto_irq(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		bool				is_init);
int rpu_sha256_crypto_block(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		bool				is_init,
		uint32_t			loop);
int rpu_sha256_iv_setup_imm(
		void __iomem		*regbase,
		uint8_t				iv[]);
int rpu_sha256_iv_get_imm(
		void __iomem		*regbase,
		uint8_t				iv[]);

int rpu_rsa2048_init(void __iomem *regbase);
int rpu_rsa2048_key_set(
		void __iomem *regbase,
		uint8_t *rsa_key,
		uint32_t rsa_key_lenth,
		enum rsa_key_type key_type,
		uint8_t *rsa_n,
		uint32_t rsa_n_lenth);
int rpu_rsa2048_rrmodn_set(
		void __iomem *regbase,
		uint8_t *rsa_rrmodn,
		uint32_t lenth);
int rpu_rsa2048_crypto_irq(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		enum rsa_key_type	key_type);

int rpu_des_init(void __iomem *regbase);
int rpu_des_crypto_irq(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		enum sym_operations	is_enc,
		enum sym_crypto_mode	mode,
		bool				is_init);

int rpu_tdes_init(void __iomem *regbase);
int rpu_tdes_crypto_irq(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		enum sym_operations	is_enc,
		enum sym_crypto_mode	mode,
		bool				is_init);

int rpu_sha1_init(void __iomem *regbase);
int rpu_sha1_crypto_irq(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		bool				is_init);
int rpu_sha1_crypto_block(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		bool				is_init,
		uint32_t			loop);
int rpu_sha1_iv_setup_imm(
		void __iomem		*regbase,
		uint8_t	iv[]);
int rpu_sha1_iv_get_imm(
		void __iomem		*regbase,
		uint8_t	iv[]);

int rpu_sm2_sm3_sm4_inst_init(void __iomem *regbase);
int rpu_sm4_init(void __iomem *regbase);
int rpu_sm4_crypto_irq(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		enum sym_operations	is_enc,
		enum sym_crypto_mode	mode,
		bool				is_init);
int rpu_sm3_init(void __iomem *regbase);
int rpu_sm3_crypto_irq(
		void __iomem		*regbase,
		const uint8_t       in[],
		uint32_t            in_len,
		uint8_t             out[],
		bool                is_init);
int rpu_sm3_crypto_block(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		bool				is_init,
		uint32_t			loop);
int rpu_sm3_iv_setup_imm(
		void __iomem		*regbase,
		uint8_t				iv[]);
int rpu_sm3_iv_get_imm(
		void __iomem		*regbase,
		uint8_t				iv[]);
int rpu_sm2_key_set_sign(
		void __iomem *regbase,
		uint8_t *sm2_key,
		uint32_t lenth);
int rpu_sm2_randomfigure_set_sign(
		void __iomem *regbase,
		uint8_t *sm2_rand,
		uint32_t lenth);
int rpu_sm2_key_set_verify(
		void __iomem *regbase,
		uint8_t *sm2_key_px,
		uint32_t lenth_px,
		uint8_t *sm2_key_py,
		uint32_t lenth_py);
int rpu_sm2_sign_init(void __iomem *regbase);
int rpu_sm2_verify_init(void __iomem *regbase);
int rpu_sm2_sign_irq(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out_r[],
		uint8_t				out_s[]);
int rpu_sm2_verify_irq(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		const uint8_t		in_r[],
		uint32_t			in_r_len,
		const uint8_t		in_s[],
		uint32_t			in_s_len,
		uint8_t				out[]);


#endif /* __HW_RPU_H__ */

